from fastapi import APIRouter, Depends, Path, HTTPException, UploadFile, File, Request
from typing import List
from service.sysDeptService import SysDeptService
from schema.sysDeptSchema import SysDeptCreate, SysDeptUpdate, PageParams
from utils.response import ResponseUtil, ResponseModel
from urllib.parse import quote
from fastapi.responses import StreamingResponse
from datetime import datetime
from io import BytesIO

router = APIRouter(prefix="/sysDept", tags=["部门表"])
service = SysDeptService()


@router.post(
    "",
    response_model=ResponseModel,
    summary="新增部门表",
    description="创建一个新的部门表。",
    response_description="返回创建成功的信息"
)
async def create(data: SysDeptCreate, request: Request):
    """新增部门表"""
    current_user = request.state.user
    creator = current_user["username"]
    result = await service.create(data, creator)
    return ResponseUtil.success(data=result, msg="创建成功")


@router.get(
    "/get/{id}",
    response_model=ResponseModel,
    summary="获取部门表详情",
    description="根据ID获取部门表的详细信息",
    response_description="返回部门表的详细信息"
)
async def get_detail(id: int):
    """获取部门表详情"""
    result = await service.get_by_id(id)
    return ResponseUtil.success(data=result)


@router.patch(
    "/update/{id}",
    response_model=ResponseModel,
    summary="更新部门表",
    description="更新指定ID的部门表信息。支持部分字段更新。",
    response_description="返回更新后的信息"
)
async def update(id: int, data: SysDeptUpdate, request: Request):
    """更新部门表"""
    current_user = request.state.user
    updater = current_user["username"]
    result = await service.update(id, data, updater)
    return ResponseUtil.success(data=result, msg="更新成功")


@router.delete(
    "/batch/{ids}",
    response_model=ResponseModel,
    summary="批量删除部门表",
    description="根据ID删除部门表，支持多个ID(用逗号分隔)。此操作不可恢复，请谨慎操作。",
    response_description="返回成功删除的数量"
)
async def delete(request: Request, ids: str = Path(..., description="ID，多个用逗号分隔，如：1,2,3")):
    """批量删除部门表"""
    try:
        id_list = [int(id.strip()) for id in ids.split(",")]
    except ValueError:
        raise ResponseUtil.error(code=400, msg="无效的ID格式")

    current_user = request.state.user
    updater = current_user["username"]
    count = await service.delete(id_list, updater)
    return ResponseUtil.success(data={"count": count}, msg=f"成功删除{count}条数据")


@router.get(
    "/page",
    response_model=ResponseModel,
    summary="分页查询部门表列表",
    description="分页获取部门表列表，支持多条件查询",
    response_description="返回分页数据，包含列表数据、总数、页码、每页大小"
)
async def get_page(
    params: PageParams = Depends()
):
    """分页获取部门表列表"""
    records, total = await service.get_page(params)
    return ResponseUtil.success(data={
        "records": records,
        "total": total,
        "page": params.page_num,
        "limit": params.page_size
    })


@router.get(
    "/export",
    summary="导出部门表数据",
    description="导出所有部门表数据到Excel文件",
    response_description="返回Excel文件"
)
async def export_data():
    """导出数据到Excel"""
    excel_data = await service.export_excel()

    filename = f"部门表数据_{datetime.now().strftime('%Y%m%d%H%M%S')}.xlsx"
    encoded_filename = quote(filename)

    headers = {
        'Content-Disposition': f'attachment; filename="{encoded_filename}"; filename*=utf-8\'\'{encoded_filename}',
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    }

    return StreamingResponse(
        BytesIO(excel_data.getvalue()),
        headers=headers,
        media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )


@router.get(
    "/importTemplate",
    summary="下载部门表导入模板",
    description="下载部门表导入的Excel模板文件",
    response_description="返回Excel模板文件"
)
async def get_import_template():
    """获取导入模板"""
    template_data = service.get_import_template()
    filename = f"部门表导入模板_{datetime.now().strftime('%Y%m%d%H%M%S')}.xlsx"
    encoded_filename = quote(filename)

    headers = {
        'Content-Disposition': f'attachment; filename="{encoded_filename}"; filename*=utf-8\'\'{encoded_filename}',
        'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    }

    return StreamingResponse(
        BytesIO(template_data.getvalue()),
        headers=headers,
        media_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    )


@router.post(
    "/import",
    response_model=ResponseModel,
    summary="导入部门表数据",
    description="通过Excel文件批量导入部门表数据",
    response_description="返回导入结果，包括成功数量和错误信息"
)
async def import_data(
    file: UploadFile = File(..., description="Excel文件")
):
    """导入数据"""
    if not file.filename.endswith(('.xls', '.xlsx')):
        return ResponseUtil.error(msg="只支持Excel文件格式（.xls, .xlsx）")

    creator = "admin"

    try:
        success_count, error_msgs = await service.import_data(file, creator)
        return ResponseUtil.success(data={
            "successCount": success_count,
            "errorMsgs": error_msgs
        }, msg=f"成功导入{success_count}条数据")
    except HTTPException as e:
        return ResponseUtil.error(msg=str(e.detail))
    except Exception as e:
        return ResponseUtil.error(msg=f"导入失败: {str(e)}")


@router.get(
    "/list",
    response_model=ResponseModel,
    summary="获取部门所有列表",
    description="获取部门所有列表",
    response_description="返回部门表"
)
async def get_all_list():
    """获取部门表详情"""
    result = await service.get_all_list()
    return ResponseUtil.success(data=result)


@router.get(
    "/exclude/{dept_id}",
    response_model=ResponseModel,
    summary="获取部门所有列表除本部门外",
    description="获取部门所有列表除本部门外",
    response_description="返回部门表"
)
async def get_exclude_list(dept_id: int):
    """获取部门表详情"""
    result = await service.get_exclude_list(dept_id)
    return ResponseUtil.success(data=result)


@router.get(
    "/user/deptTree",
    response_model=ResponseModel,
    summary="获取部门所有列表树形结构",
    description="获取部门所有列表树形结构",
    response_description="返回部门表树形结构"
)
async def get_user_dept(request: Request):
    """获取部门表详情"""
    current_user = request.state.user
    user_id = current_user["user_id"]
    result = await service.get_dept_tree(user_id)
    return ResponseUtil.success(data=result)
